/*******************************************************************************
  * @file                   shell.c
  * @Author:                MQjehovah                 mail:MQjehovah@hotmail.com
  * @version                1.0.0
  * @date                   2017.11.22
  * @brief                  
  ******************************************************************************
  * @attention
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "shell.h"
#include "ring_buffer.h"
#include "USART.h"
#include "delay.h"
#include <stdlib.h>
/* Definition ----------------------------------------------------------------*/
char CMD_LINE_BUF[CMD_REC_BUF_LEN]; //指令接收缓冲区

/* Functions -----------------------------------------------------------------*/
/*******************************************************************************
  * @brief  shell循环            
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
void shell_loop(void)
{
    while (1)
    {
        char *cmd = shell_readline(CMD_LINE_BUF);
        shell_process(cmd);
        simple_delay_ms(100);
    }
}
/*******************************************************************************
  * @brief  从缓冲区中读取一行指令              
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
char *shell_readline(char *buffer)
{
    u32 seek = 0;
    shell_send_str(PROMPT);
    while (1)
    {
        // if (pE34_RX_BUF->lenth <= 0)
        //     continue;
        if (!shell_read_char(&buffer[seek]))
            continue;
        switch (buffer[seek])
        {
        case '\r': /* Enter */
        case '\n': //回车表示命令输入结束
            shell_send_str("\r\n");
            if (seek == 0)
                return (char *)-1; //空指令不处理
            buffer[seek] = '\0';   //字符串末尾添加结束符
            // shell_send_str(buffer);
            return buffer;
        case '\0': /* nul */
            continue;
        case 0x03: /* ^C - break */
            //CTRL+C表示取消命令输入
            return ((char *)-1);
        case 0x15: /* ^U - erase line */
            continue;
        case 0x17: /* ^W - erase word */
            //CTRL+W表示删除一个词
            continue;
        case 0x08: /* ^H  - backspace */
        case 0x7F: /* DEL - backspace */
            //表示删除一个字符
            if (seek > 0)
            {
                shell_send_str("\b \b");
                seek--;
            }
            continue;
        default:
            shell_send_char(buffer[seek]);
            seek++;
            break;
        } //switch
    }
}
/*******************************************************************************
  * @brief  指令处理程序              
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
int shell_process(char *cmd)
{
    static char *argv[CMD_ARG_MAX_CNT] = {0};
    u8 argc = 0;
    argv[argc++] = cmd;

    if (cmd == (char *)-1) //获取指令数据错误
        return 0;
    //分词
    while (1)
    {
        if (*cmd == '\0')
            break;
        if (*cmd == ' ')
        {
            *cmd = '\0';
            argv[argc++] = ++cmd;
            continue;
        }
        cmd++;
    }
    if (string_compare(argv[0], "help"))
    {
        shell_send_str("Support Command:\r\n");
        shell_send_str("help:   show help info.\r\n");
        shell_send_str("time:   show system time.\r\n");
        shell_send_str("info:   show system info.\r\n");
        shell_send_str("step:   set step pwm frequest.\r\n");
        shell_send_str("reboot: reboot system.\r\n");
        return 1;
    }
    if (string_compare(argv[0], "time"))
    {
        shell_send_number(sys_Time, 10);
        shell_send_str("\r\n");
        return 1;
    }
    if (string_compare(argv[0], "info"))
    {
        u32 CpuID[3];
        u32 Lock_Code;
        CpuID[0] = *(u32 *)(0x1ffff7e8);
        CpuID[1] = *(u32 *)(0x1ffff7ec);
        CpuID[2] = *(u32 *)(0x1ffff7f0);
        //加密算法,很简单的加密算法
        Lock_Code = (CpuID[0] >> 1) + (CpuID[1] >> 2) + (CpuID[2] >> 3);
        shell_send_str("Chip Id:0x");
        shell_send_number(Lock_Code, 16);
        shell_send_str("\r\n");
        shell_send_str("stack:0x");
        shell_send_number(*(u32 *)0x8000000 - __get_MSP(), 16);
        shell_send_str("\r\n");
        return 1;
    }
    if (string_compare(argv[0], "step"))
    {
        u32 addr = 0;
        if (argc > 1)
        {
            if (argv[1][0] == '0' && argv[1][1] == 'x')
            {
                addr = strtol(argv[1], (char **)NULL, 16);
            }
            else
            {
                addr = strtol(argv[1], (char **)NULL, 10);
            }
        }
        // nARR = (1000000 / (8000)) - 1;
        // TIM_SetAutoreload(TIM2, 125);
        // TIM_SetCompare2(TIM2, 125 >> 1);
        stepper.step = addr;
        shell_send_number(addr, 10);
        shell_send_str("\r\n");
        return 1;
    }
    if (string_compare(argv[0], "load"))
    {
        // Ymodem_Receive((uint8_t *)ymodem_rec_buf);
        return 1;
    }
    if (string_compare(argv[0], "reboot"))
    {
        __disable_fault_irq();
        NVIC_SystemReset();
        return 1;
    }
    shell_send_str("Unsupport Command\r\n");
    return 0;
}
/*******************************************************************************
  * @brief  字符串比较            
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
u8 string_compare(char *str1, char *str2)
{
    int seek = 0;
    while (1)
    {
        if (str1[seek] == str2[seek])
        {
            if (str1[seek++] == '\0')
                return 1;
            continue;
        }
        return 0;
    }
}

/*********************************END OF FILE**********************************/
